//************************************************************************
//Developed by Guo Ming Li 2009/2010
//Source code:
//  The source code may be freely modified or used but this credit section may not be removed 
//  The original author must be notified of any modifications plus a copy of 
//  the changed source code
//Contact info: mailto://gming.li@gmail.com
//************************************************************************
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.BizTalk.ExplorerOM;

namespace GML.BizTalk.OperationManager.Library
{
    public class OrchestrationStateManagement
    {
        public static List<GML.BizTalk.OperationManager.MSBTSOperations.Orchestration> GetStartedOrchestrations(string btsAppName, string btsDbServerName, string btsMgntDbName)
        {
            return GetOrchestrations(btsAppName, true, btsDbServerName, btsMgntDbName);
        }
        public static List<GML.BizTalk.OperationManager.MSBTSOperations.Orchestration> GetAllOrchestrations(string btsAppName, string btsDbServerName, string btsMgntDbName)
        {
            return GetOrchestrations(btsAppName, null, btsDbServerName, btsMgntDbName);
        }

        public static List<GML.BizTalk.OperationManager.MSBTSOperations.Orchestration> GetUnenlistedOrchestrations(string btsAppName, string btsDbServerName, string btsMgntDbName)
        {
            return GetOrchestrations(btsAppName, false, btsDbServerName, btsMgntDbName);
        }

        private static List<Microsoft.BizTalk.ExplorerOM.BtsOrchestration> GetBTSOrchestrations(string btsAppName, Nullable<bool> started, string btsDbServerName, string btsMgntDbName)
        {
            BtsCatalogExplorer catalog = new BtsCatalogExplorer();
            catalog.ConnectionString = Helper.GetConnectionString(btsDbServerName, btsMgntDbName);
            List<Microsoft.BizTalk.ExplorerOM.BtsOrchestration> ListOfOrchestrations = new List<BtsOrchestration>();
            Application application = null;
            BtsOrchestrationCollection orchestrations = null;
            try
            {
                application = Applications.GetApplication(btsAppName, btsDbServerName, btsMgntDbName);
                orchestrations = application.Orchestrations;

                foreach (BtsOrchestration orchestration in orchestrations)
                {
                    if ((started != null && started.Value == true && orchestration.Status.ToString().Equals("Started")) ||
                        (started != null && started.Value == false && orchestration.Status.ToString().Equals("Unenlisted")) ||
                         started == null
                        )
                    {

                        ListOfOrchestrations.Add(orchestration);
                    }
                }
                return ListOfOrchestrations;
            }
            catch (Exception e)
            {
                Logger.doLog(Guid.NewGuid().ToString(), e.Message, Logger.ServerityLevel.ERROR);
                Logger.doLog(Guid.NewGuid().ToString(), e.StackTrace, Logger.ServerityLevel.ERROR);
                catalog.DiscardChanges();
                throw;
            }
            finally
            {
                //if (catalog != null) catalog.Dispose();
                catalog = null;
                ListOfOrchestrations = null;
                application = null;
                orchestrations = null;
            }
        }

        private static List<GML.BizTalk.OperationManager.MSBTSOperations.Orchestration> GetOrchestrations(string btsAppName, Nullable<bool> started, string btsDbServerName, string btsMgntDbName)
        {
            BtsCatalogExplorer catalog = new BtsCatalogExplorer();
            catalog.ConnectionString = Helper.GetConnectionString(btsDbServerName, btsMgntDbName);
            List<GML.BizTalk.OperationManager.MSBTSOperations.Orchestration> ListOfOrchestrations =
                new List<GML.BizTalk.OperationManager.MSBTSOperations.Orchestration>();
            GML.BizTalk.OperationManager.MSBTSOperations.Orchestration GMLOrch = null;
            GML.BizTalk.OperationManager.MSBTSOperations.BtsAssembly GMLAssembly = null;
            Application application = null;
            BtsOrchestrationCollection orchestrations = null;
            try
            {
                application = Applications.GetApplication(btsAppName, btsDbServerName, btsMgntDbName);
                orchestrations = application.Orchestrations;

                foreach (BtsOrchestration orchestration in orchestrations)
                {
                    if ((started != null && started.Value == true && orchestration.Status.ToString().Equals("Started")) ||
                        (started != null && started.Value == false && orchestration.Status.ToString().Equals("Unenlisted")) ||
                         started == null
                        )
                    {
                        GMLAssembly = new GML.BizTalk.OperationManager.MSBTSOperations.BtsAssembly();
                        GMLAssembly.Culture = orchestration.BtsAssembly.Culture;
                        GMLAssembly.DisplayName = orchestration.BtsAssembly.DisplayName;
                        GMLAssembly.Name = orchestration.BtsAssembly.Name;
                        GMLAssembly.PublicKeyToken = orchestration.BtsAssembly.PublicKeyToken;
                        GMLAssembly.Version = orchestration.BtsAssembly.Version;

                        GMLOrch = new GML.BizTalk.OperationManager.MSBTSOperations.Orchestration();
                        GMLOrch.BtsAssembly = GMLAssembly;
                        GMLOrch.Fullname = orchestration.FullName;
                        GMLOrch.Hostname = ((orchestration.Host == null) ? null : orchestration.Host.Name);
                        GMLOrch.Status = orchestration.Status.ToString();
                        GMLOrch.ApplicationName = btsAppName;
                        GMLOrch.BtsDbServerName = string.Empty; // btsDbServerName;
                        GMLOrch.BtsManagmentDbName = string.Empty; // btsMgntDbName;

                        ListOfOrchestrations.Add(GMLOrch);
                    }
                }
                return ListOfOrchestrations;
            }
            catch (Exception e)
            {
                Logger.doLog(Guid.NewGuid().ToString(), e.Message, Logger.ServerityLevel.ERROR);
                Logger.doLog(Guid.NewGuid().ToString(), e.StackTrace, Logger.ServerityLevel.ERROR);
                catalog.DiscardChanges();
                throw;
            }
            finally
            {
                //if (catalog != null) catalog.Dispose();
                catalog = null;
                ListOfOrchestrations = null;
                GMLOrch = null;
                GMLAssembly = null;
                application = null;
                orchestrations = null;
            }
        }
        public static BtsOrchestrationCollection ListOrchestrations(string btsAppName, string btsDbServerName, string btsMgntDbName)
        {
            BtsCatalogExplorer catalog = new BtsCatalogExplorer();
            catalog.ConnectionString = Helper.GetConnectionString(btsDbServerName, btsMgntDbName);
            Application application = null;
            //BtsOrchestrationCollection orchestrations = null;
            try
            {
                application = Applications.GetApplication(btsAppName, btsDbServerName, btsMgntDbName);
                return application.Orchestrations;
                //orchestrations = application.Orchestrations;

                //foreach (BtsOrchestration orchestration in orchestrations)
                //{
                //    Microsoft.BizTalk.ExplorerOM.OrchestrationStatus status = orchestration.Status;

                    //System.Diagnostics.Debug.WriteLine(
                    //   "orchestration.Status.ToString() = " + orchestration.Status.ToString() + Environment.NewLine +
                    //   "orchestration.AssemblyQualifiedName = " + orchestration.AssemblyQualifiedName + Environment.NewLine +
                    //   "orchestration.AutoResumeSuspendedInstances.ToString() = " + orchestration.AutoResumeSuspendedInstances.ToString() + Environment.NewLine +
                    //   "orchestration.AutoSuspendRunningInstances.ToString() = " + orchestration.AutoSuspendRunningInstances.ToString() + Environment.NewLine +
                    //   "orchestration.AutoTerminateInstances.ToString() = " + orchestration.AutoTerminateInstances.ToString() + Environment.NewLine +
                    //   "orchestration.Description = " + orchestration.Description + Environment.NewLine +
                    //   "orchestration.FullName = " + orchestration.FullName + Environment.NewLine +
                    //   "orchestration.Host.Name = " + ((orchestration.Host==null)?"":orchestration.Host.Name) + Environment.NewLine +
                    //   "orchestration.BtsAssembly.Culture = " + orchestration.BtsAssembly.Culture + Environment.NewLine +
                    //   "orchestration.BtsAssembly.DisplayName = " + orchestration.BtsAssembly.DisplayName + Environment.NewLine +
                    //   "orchestration.BtsAssembly.IsSystem.ToString() = " + orchestration.BtsAssembly.IsSystem.ToString() + Environment.NewLine +
                    //   "orchestration.BtsAssembly.Name = " + orchestration.BtsAssembly.Name + Environment.NewLine +
                    //   "orchestration.BtsAssembly.PublicKeyToken = " + orchestration.BtsAssembly.PublicKeyToken + Environment.NewLine +
                    //   "orchestration.BtsAssembly.Version = " + orchestration.BtsAssembly.Version + Environment.NewLine +
                    //   "orchestration.BtsAssembly.IsSystem.ToString() = " + orchestration.BtsAssembly.IsSystem.ToString() + Environment.NewLine +
                    //   "orchestration.BtsAssembly.IsSystem.ToString() = " + orchestration.BtsAssembly.IsSystem.ToString() + Environment.NewLine +
                    //   "");
                    //Logger.doLog(Guid.NewGuid().ToString(), "orchestration.Status.ToString() = " + orchestration.Status.ToString() + Environment.NewLine +
                    //   "orchestration.AssemblyQualifiedName = " + orchestration.AssemblyQualifiedName + Environment.NewLine +
                    //   "orchestration.AutoResumeSuspendedInstances.ToString() = " + orchestration.AutoResumeSuspendedInstances.ToString() + Environment.NewLine +
                    //   "orchestration.AutoSuspendRunningInstances.ToString() = " + orchestration.AutoSuspendRunningInstances.ToString() + Environment.NewLine +
                    //   "orchestration.AutoTerminateInstances.ToString() = " + orchestration.AutoTerminateInstances.ToString() + Environment.NewLine +
                    //   "orchestration.Description = " + orchestration.Description + Environment.NewLine +
                    //   "orchestration.FullName = " + orchestration.FullName + Environment.NewLine +
                    //   "orchestration.Host.Name = " + ((orchestration.Host == null) ? "" : orchestration.Host.Name) + Environment.NewLine +
                    //   "orchestration.BtsAssembly.Culture = " + orchestration.BtsAssembly.Culture + Environment.NewLine +
                    //   "orchestration.BtsAssembly.DisplayName = " + orchestration.BtsAssembly.DisplayName + Environment.NewLine +
                    //   "orchestration.BtsAssembly.IsSystem.ToString() = " + orchestration.BtsAssembly.IsSystem.ToString() + Environment.NewLine +
                    //   "orchestration.BtsAssembly.Name = " + orchestration.BtsAssembly.Name + Environment.NewLine +
                    //   "orchestration.BtsAssembly.PublicKeyToken = " + orchestration.BtsAssembly.PublicKeyToken + Environment.NewLine +
                    //   "orchestration.BtsAssembly.Version = " + orchestration.BtsAssembly.Version + Environment.NewLine +
                    //   "orchestration.BtsAssembly.IsSystem.ToString() = " + orchestration.BtsAssembly.IsSystem.ToString() + Environment.NewLine +
                    //   "orchestration.BtsAssembly.IsSystem.ToString() = " + orchestration.BtsAssembly.IsSystem.ToString() + Environment.NewLine +
                    //   "", Logger.ServerityLevel.INFO);
                    
                //}
                //return ;
            }
            catch (Exception e)
            {
                Logger.doLog(Guid.NewGuid().ToString(), e.Message, Logger.ServerityLevel.ERROR);
                Logger.doLog(Guid.NewGuid().ToString(), e.StackTrace, Logger.ServerityLevel.ERROR);
                catalog.DiscardChanges();
                throw;
            }
            finally
            {
                //if (catalog != null) catalog.Dispose();
                catalog = null;
                application = null;
                //orchestrations = null;
            }
        }
        public static void ListAssemblies(string btsDbServerName, string btsMgntDbName)
        {
            // Create the root object and set the connection string
            BtsCatalogExplorer catalog = new BtsCatalogExplorer();
            catalog.ConnectionString = Helper.GetConnectionString(btsDbServerName, btsMgntDbName);
            BtsAssemblyCollection assemblies = null;
            try
            {
                assemblies = catalog.Assemblies;
                foreach (BtsAssembly assembly in assemblies)
                {
                    System.Diagnostics.Debug.WriteLine(
                       "assembly.Application.Name = " + assembly.Application.Name + Environment.NewLine +
                       "assembly.Culture = " + assembly.Culture + Environment.NewLine +
                       "assembly.DisplayName = " + assembly.DisplayName + Environment.NewLine +
                       "assembly.IsSystem.ToString() = " + assembly.IsSystem.ToString() + Environment.NewLine +
                       "assembly.PublicKeyToken = " + assembly.PublicKeyToken + Environment.NewLine +
                       "assembly.Version = " + assembly.Version + Environment.NewLine +
                       "");
                    Logger.doLog(Guid.NewGuid().ToString(), "assembly.Application.Name = " + assembly.Application.Name + Environment.NewLine +
                       "assembly.Culture = " + assembly.Culture + Environment.NewLine +
                       "assembly.DisplayName = " + assembly.DisplayName + Environment.NewLine +
                       "assembly.IsSystem.ToString() = " + assembly.IsSystem.ToString() + Environment.NewLine +
                       "assembly.PublicKeyToken = " + assembly.PublicKeyToken + Environment.NewLine +
                       "assembly.Version = " + assembly.Version + Environment.NewLine +
                       "", Logger.ServerityLevel.INFO);
                }
                catalog.DiscardChanges();
            }
            catch (Exception e)
            {
                Logger.doLog(Guid.NewGuid().ToString(), e.Message, Logger.ServerityLevel.ERROR);
                Logger.doLog(Guid.NewGuid().ToString(), e.StackTrace, Logger.ServerityLevel.ERROR);
                catalog.DiscardChanges();
                throw e;
            }
            finally
            {
                //if (catalog != null) catalog.Dispose();
                catalog = null;
                assemblies = null;
            }
        }
        public static BtsAssembly FindAssemblyByFullName(BtsAssemblyCollection assemblies, string fullName)
        {
            foreach (BtsAssembly assembly in assemblies)
            {
                if (assembly.DisplayName == fullName)
                    return assembly;
            }
            return null;
        }
        public static bool UpdateOrchestrations(GML.BizTalk.OperationManager.MSBTSOperations.Orchestration [] orchs, string btsDbServerName, string btsMgntDbName)
        {
            // Create the root object and set the connection string
            BtsCatalogExplorer catalog = new BtsCatalogExplorer();
            catalog.ConnectionString = Helper.GetConnectionString(btsDbServerName, btsMgntDbName);
            string orchestrationAssembly = null;
            string orchestrationName = null;
            BtsAssembly assembly = null;
            BtsOrchestration orchestration = null;

            try
            {
                foreach (GML.BizTalk.OperationManager.MSBTSOperations.Orchestration orch in orchs)
                {
                    orchestrationAssembly = orch.BtsAssembly.DisplayName;
                    //string orchestrationAssemblyV2 = "HelloWorld, Version=2.0.0.0, Culture=neutral, PublicKeyToken=99561c477e487f14";
                    orchestrationName = orch.Fullname;
                    //string orchestrationName = "Microsoft.Samples.BizTalk.HelloWorld.HelloSchedule";
                    assembly = FindAssemblyByFullName(catalog.Assemblies, orchestrationAssembly);
                    if (assembly == null) continue;

                    orchestration = assembly.Orchestrations[orchestrationName];
                    if (orchestration == null) continue;
                    bool blnSaveChanges = false;

                    if (orch.Status.Equals("Started"))
                    {
                        if (orchestration.Status != Microsoft.BizTalk.ExplorerOM.OrchestrationStatus.Started)
                        {
                            orchestration.Status = Microsoft.BizTalk.ExplorerOM.OrchestrationStatus.Started;
                            System.Diagnostics.Debug.WriteLine("Starting " + orch.Fullname + ", " + orch.BtsAssembly.DisplayName);
                            Logger.doLog(Guid.NewGuid().ToString(), "Starting " + orch.Fullname + ", " + orch.BtsAssembly.DisplayName, Logger.ServerityLevel.INFO);
                            blnSaveChanges = true;
                        }
                        else
                        {
                            System.Diagnostics.Debug.WriteLine("Already started: " + orch.Fullname + ", " + orch.BtsAssembly.DisplayName);
                            Logger.doLog(Guid.NewGuid().ToString(), "Already started: " + orch.Fullname + ", " + orch.BtsAssembly.DisplayName, Logger.ServerityLevel.INFO);
                            blnSaveChanges = false;
                        }
                    }
                    else if (orch.Status.Equals("Unenlisted"))
                    {
                        if (orchestration.Status != Microsoft.BizTalk.ExplorerOM.OrchestrationStatus.Unenlisted)
                        {
                            orchestration.Status = Microsoft.BizTalk.ExplorerOM.OrchestrationStatus.Unenlisted;
                            System.Diagnostics.Debug.WriteLine("Unenlisting " + orch.Fullname + ", " + orch.BtsAssembly.DisplayName);
                            Logger.doLog(Guid.NewGuid().ToString(), "Unenlisting " + orch.Fullname + ", " + orch.BtsAssembly.DisplayName, Logger.ServerityLevel.INFO);
                            blnSaveChanges = true;
                        }
                        else
                        {
                            System.Diagnostics.Debug.WriteLine("Already unenlisted: " + orch.Fullname + ", " + orch.BtsAssembly.DisplayName);
                            Logger.doLog(Guid.NewGuid().ToString(), "Already unenlisted: " + orch.Fullname + ", " + orch.BtsAssembly.DisplayName, Logger.ServerityLevel.INFO);
                            blnSaveChanges = false;
                        }
                    }
                    else if (orch.Status.Equals("Enlisted"))
                    {
                        if (orchestration.Status != Microsoft.BizTalk.ExplorerOM.OrchestrationStatus.Enlisted)
                        {
                            orchestration.Status = Microsoft.BizTalk.ExplorerOM.OrchestrationStatus.Enlisted;
                            System.Diagnostics.Debug.WriteLine("Enlisting " + orch.Fullname + ", " + orch.BtsAssembly.DisplayName);
                            Logger.doLog(Guid.NewGuid().ToString(), "Enlisting " + orch.Fullname + ", " + orch.BtsAssembly.DisplayName, Logger.ServerityLevel.INFO);
                            blnSaveChanges = true;
                        }
                        else
                        {
                            System.Diagnostics.Debug.WriteLine("Already enlisted: " + orch.Fullname + ", " + orch.BtsAssembly.DisplayName);
                            Logger.doLog(Guid.NewGuid().ToString(), "Already enlisted: " + orch.Fullname + ", " + orch.BtsAssembly.DisplayName, Logger.ServerityLevel.INFO);
                            blnSaveChanges = false;
                        }
                    }
                    if (blnSaveChanges)
                    {
                        // Commit the accumulated changes transactionally
                        System.Diagnostics.Debug.WriteLine("Starting to save BtsServerCatalog changes");
                        Logger.doLog(Guid.NewGuid().ToString(), "Starting to save BtsServerCatalog changes", Logger.ServerityLevel.INFO);
                        catalog.SaveChanges();
                        System.Diagnostics.Debug.WriteLine("Done saving BtsServerCatalog changes");
                        Logger.doLog(Guid.NewGuid().ToString(), "Done saving BtsServerCatalog changes", Logger.ServerityLevel.INFO);
                    }

                    //perform clean up
                    //orchestrationAssembly = null;
                    //orchestrationName = null;
                    //assembly = null;
                    //orchestration = null;

                }
                System.Diagnostics.Debug.WriteLine("Starting to dispose BtsServerCatalog");
                Logger.doLog(Guid.NewGuid().ToString(), "Starting to dispose BtsServerCatalog", Logger.ServerityLevel.INFO);
                catalog.Dispose();
                System.Diagnostics.Debug.WriteLine("Done disposing BtsServerCatalog");
                Logger.doLog(Guid.NewGuid().ToString(), "Done disposing BtsServerCatalog", Logger.ServerityLevel.INFO);
                return true;
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine("Starting to DiscardChanges for BtsServerCatalog");
                Logger.doLog(Guid.NewGuid().ToString(), "Starting to DiscardChanges for BtsServerCatalog", Logger.ServerityLevel.INFO);
                catalog.DiscardChanges();
                System.Diagnostics.Debug.WriteLine("Done DiscardChanges for BtsServerCatalog");
                Logger.doLog(Guid.NewGuid().ToString(), "Done DiscardChanges for BtsServerCatalog", Logger.ServerityLevel.INFO);
                throw e;
            }
            finally
            {
                //perform clean up
                //if (catalog != null) catalog.Dispose();
                catalog = null;
                orchestrationAssembly = null;
                orchestrationName = null;
                assembly = null;
                orchestration = null;
            }
    }
        public static bool UpdateOrchestration(GML.BizTalk.OperationManager.MSBTSOperations.Orchestration orch, string btsDbServerName, string btsMgntDbName)
        {                
            GML.BizTalk.OperationManager.MSBTSOperations.Orchestration[] orchs = null;
            try
            {
                //orchs = new GML.BizTalk.OperationManager.MSBTSOperations.Orchestration[1];
                //orchs[0] = orch;
                orchs = new[] { orch };
                return UpdateOrchestrations(orchs, btsDbServerName, btsMgntDbName);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                orchs = null;
            }
        }

        public static List<GML.BizTalk.OperationManager.MSBTSOperations.Orchestration> GetGMLOrchestrations(
            List<Microsoft.BizTalk.ExplorerOM.BtsOrchestration> btsOrchs, Nullable<bool> blnSetStatus, string OrchStatus)
        {
            if (btsOrchs == null) return null;

            List<GML.BizTalk.OperationManager.MSBTSOperations.Orchestration> ListOfOrchestrations =
                new List<GML.BizTalk.OperationManager.MSBTSOperations.Orchestration>();
            GML.BizTalk.OperationManager.MSBTSOperations.Orchestration GMLOrch = null;
            GML.BizTalk.OperationManager.MSBTSOperations.BtsAssembly GMLAssembly = null;
            try
            {
                foreach (BtsOrchestration orchestration in btsOrchs)
                {
                    GMLAssembly = new GML.BizTalk.OperationManager.MSBTSOperations.BtsAssembly();
                    GMLAssembly.Culture = orchestration.BtsAssembly.Culture;
                    GMLAssembly.DisplayName = orchestration.BtsAssembly.DisplayName;
                    GMLAssembly.Name = orchestration.BtsAssembly.Name;
                    GMLAssembly.PublicKeyToken = orchestration.BtsAssembly.PublicKeyToken;
                    GMLAssembly.Version = orchestration.BtsAssembly.Version;

                    GMLOrch = new GML.BizTalk.OperationManager.MSBTSOperations.Orchestration();
                    GMLOrch.BtsAssembly = GMLAssembly;
                    GMLOrch.Fullname = orchestration.FullName;
                    GMLOrch.Hostname = ((orchestration.Host == null) ? null : orchestration.Host.Name);
                    if (blnSetStatus != null && blnSetStatus.Value == true)
                    {
                        GMLOrch.Status = OrchStatus;
                    }
                    GMLOrch.ApplicationName = orchestration.Application.Name;
                    GMLOrch.BtsDbServerName = string.Empty; // btsDbServerName;
                    GMLOrch.BtsManagmentDbName = string.Empty; // btsMgntDbName;

                    ListOfOrchestrations.Add(GMLOrch);
                }
                return ListOfOrchestrations;
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine(e.Message + Environment.NewLine + e.StackTrace);
                Logger.doLog(Guid.NewGuid().ToString(), e.Message, Logger.ServerityLevel.ERROR);
                Logger.doLog(Guid.NewGuid().ToString(), e.StackTrace, Logger.ServerityLevel.ERROR);
                throw e;
            }
            finally
            {
                ListOfOrchestrations = null;
                GMLOrch = null;
                GMLAssembly = null;
            }
        }

        public static GML.BizTalk.OperationManager.MSBTSOperations.Orchestration[] GetToBeUnenlistedList
            (GML.BizTalk.OperationManager.MSBTSOperations.Orchestration[] excludeOrchs, string btsDbServerName, string btsMgntDbName)
        {
            List<Microsoft.BizTalk.ExplorerOM.BtsOrchestration> allOrchs = null;
            List<Microsoft.BizTalk.ExplorerOM.BtsOrchestration> toBeUnenlistedBtsOrchs = new List<Microsoft.BizTalk.ExplorerOM.BtsOrchestration>();
            List<Microsoft.BizTalk.ExplorerOM.BtsOrchestration> toBeUnenlistedBtsOrchs_New = new List<Microsoft.BizTalk.ExplorerOM.BtsOrchestration>();
            List<Microsoft.BizTalk.ExplorerOM.BtsOrchestration> toBeStartedBtsOrchs = new List<Microsoft.BizTalk.ExplorerOM.BtsOrchestration>();

            List<GML.BizTalk.OperationManager.MSBTSOperations.Orchestration> toBeUnenlistedOrchs = new List<GML.BizTalk.OperationManager.MSBTSOperations.Orchestration>();
            List<GML.BizTalk.OperationManager.MSBTSOperations.Orchestration> toBeStartedOrchs = new List<GML.BizTalk.OperationManager.MSBTSOperations.Orchestration>();
            string btsAppName = excludeOrchs[0].ApplicationName;
            bool toBeUnenlisted = true;
            //bool toBeStopped = false;
            try
            {
                System.Diagnostics.Debug.WriteLine("Starting to generate toBeUnenlistedBtsOrchs and toBeStartedBtsOrchs");

                Logger.doLog(Guid.NewGuid().ToString(), "Starting to generate toBeUnenlistedBtsOrchs and toBeStartedBtsOrchs", Logger.ServerityLevel.INFO);
                allOrchs = GML.BizTalk.OperationManager.Library.OrchestrationStateManagement.GetBTSOrchestrations(btsAppName, null, btsDbServerName, btsMgntDbName);
                foreach (Microsoft.BizTalk.ExplorerOM.BtsOrchestration orch in allOrchs)
                {
                    Microsoft.BizTalk.ExplorerOM.BtsOrchestrationCollection orchInvokedOrchs = orch.InvokedOrchestrations;
                    toBeUnenlisted = true;
                    foreach (GML.BizTalk.OperationManager.MSBTSOperations.Orchestration excludeOrch in excludeOrchs)
                    {
                        if (excludeOrch.Fullname.Equals(orch.FullName) &&
                            excludeOrch.BtsAssembly.DisplayName.Equals(orch.BtsAssembly.DisplayName))
                        {
                            toBeUnenlisted = false;
                            break;
                        }
                    }
                    if (toBeUnenlisted)
                    {

                        //the orchestrations being invoked needs to be started, hence added to {toBeStartedBtsOrchs}
                        if (orchInvokedOrchs != null && orchInvokedOrchs.Count > 0)
                        {
                            foreach (BtsOrchestration tempOrch in orchInvokedOrchs)
                            {
                                if (!toBeStartedBtsOrchs.Contains(tempOrch))
                                {
                                    toBeStartedBtsOrchs.Add(tempOrch);
                                }
                            }
                        }

                        //add all the orchestration that needs to be unenlisted to {toBeUnenlistedBtsOrchs}
                        toBeUnenlistedBtsOrchs.Add(orch);
                    }
                }

                System.Diagnostics.Debug.WriteLine("Finished generating toBeUnenlistedBtsOrchs and toBeStartedBtsOrchs");
                System.Diagnostics.Debug.WriteLine("Starting to remove orch from toBeUnenlistedBtsOrchs that needs to be started (from toBeStartedBtsOrchs)");
                Logger.doLog(Guid.NewGuid().ToString(), "Finished generating toBeUnenlistedBtsOrchs and toBeStartedBtsOrchs", Logger.ServerityLevel.INFO);
                Logger.doLog(Guid.NewGuid().ToString(), "Starting to remove orch from toBeUnenlistedBtsOrchs that needs to be started (from toBeStartedBtsOrchs)", Logger.ServerityLevel.INFO);
                /****************************
                 * Remove the orchestration to be started (exists in {toBeStartedBtsOrchs}) from the {toBeUnenlistedBtsOrchs}
                 * {toBeUnenlistedBtsOrchs_New} contains a list of orchestration to be un-enlisted
                 * {toBeStartedBtsOrchs} contains a list of orchestration to be started
                 ****************************
                 */
                foreach (BtsOrchestration tempOrch in toBeUnenlistedBtsOrchs)
                {
                    toBeUnenlisted = true;
                    foreach (BtsOrchestration tempOrch2 in toBeStartedBtsOrchs)
                    {
                        if (tempOrch.FullName.Equals(tempOrch2.FullName) &&
                            tempOrch.BtsAssembly.DisplayName.Equals(tempOrch2.BtsAssembly.DisplayName))
                        {
                            Logger.doLog(Guid.NewGuid().ToString(), "===> Removing orch: " + tempOrch.FullName + ", " + tempOrch.BtsAssembly.DisplayName, Logger.ServerityLevel.INFO);
                            toBeUnenlisted = false;
                            break;
                        }
                    }
                    if (toBeUnenlisted)
                    {
                        toBeUnenlistedBtsOrchs_New.Add(tempOrch);
                    }
                }
                System.Diagnostics.Debug.WriteLine("Finished removing orch from toBeUnenlistedBtsOrchs that needs to be started (from toBeStartedBtsOrchs)");
                Logger.doLog(Guid.NewGuid().ToString(), "Finished removing orch from toBeUnenlistedBtsOrchs that needs to be started (from toBeStartedBtsOrchs)", Logger.ServerityLevel.INFO);

                if (toBeUnenlistedOrchs == null) return null;

                List<GML.BizTalk.OperationManager.MSBTSOperations.Orchestration> sortedListOfOrchs = new List<GML.BizTalk.OperationManager.MSBTSOperations.Orchestration>();
                toBeUnenlistedOrchs = GetGMLOrchestrations(toBeUnenlistedBtsOrchs_New, true, "Unenlisted");
                toBeStartedOrchs = GetGMLOrchestrations(toBeStartedBtsOrchs, true, "Started");
                foreach (GML.BizTalk.OperationManager.MSBTSOperations.Orchestration orch in toBeUnenlistedOrchs)
                {
                    orch.BtsDbServerName = btsDbServerName;
                    orch.BtsManagmentDbName = btsMgntDbName;
                    sortedListOfOrchs.Add(orch);
                    System.Diagnostics.Debug.WriteLine("{toBeUnenlistedOrchs} ==> " + orch.Fullname + ", " + orch.BtsAssembly.DisplayName);
                    Logger.doLog(Guid.NewGuid().ToString(), "{toBeUnenlistedOrchs} ==> " + orch.Fullname + ", " + orch.BtsAssembly.DisplayName, Logger.ServerityLevel.INFO);
                    //orch.GetInvokedOrchestrations();
                }
                foreach (GML.BizTalk.OperationManager.MSBTSOperations.Orchestration orch in toBeStartedOrchs)
                {
                    orch.BtsDbServerName = btsDbServerName;
                    orch.BtsManagmentDbName = btsMgntDbName;
                    sortedListOfOrchs.Add(orch);
                    System.Diagnostics.Debug.WriteLine("{toBeStartedOrchs} ==> " + orch.Fullname + ", " + orch.BtsAssembly.DisplayName);
                    Logger.doLog(Guid.NewGuid().ToString(), "{toBeStartedOrchs} ==> " + orch.Fullname + ", " + orch.BtsAssembly.DisplayName, Logger.ServerityLevel.INFO);
                    //orch.GetInvokedOrchestrations();
                }

                //System.Diagnostics.Debug.WriteLine("--------------------------------------------------------------");

                //sortedListOfOrchs.Sort();


                System.Diagnostics.Debug.WriteLine("--------------------------------------------------------------");
                Logger.doLog(Guid.NewGuid().ToString(), "--------------------------------------------------------------", Logger.ServerityLevel.INFO);
                //foreach (GML.BizTalk.OperationManager.MSBTSOperations.Orchestration orch in sortedListOfOrchs)
                //{
                //System.Diagnostics.Debug.WriteLine(orch.Fullname + ", " + orch.BtsAssembly.DisplayName);
                //}
                return sortedListOfOrchs.ToArray();
            }
            catch (Exception e)
            {
                Logger.doLog(Guid.NewGuid().ToString(), e.Message, Logger.ServerityLevel.ERROR);
                Logger.doLog(Guid.NewGuid().ToString(), e.StackTrace, Logger.ServerityLevel.ERROR);
                throw e;
            }
            finally
            {
                allOrchs = null;
                toBeUnenlistedBtsOrchs = null;
                toBeUnenlistedBtsOrchs_New = null;
                toBeStartedBtsOrchs = null;

                toBeUnenlistedOrchs = null;
                toBeStartedOrchs = null;
                btsAppName = null;
            }
        }

        public static bool RemoveAllOrchestrationBindings(string btsDbServerName, string btsMgntDbName, string sBtsAppName)
        {
            BtsCatalogExplorer root = new BtsCatalogExplorer();

            try
            {
                root.ConnectionString = Helper.GetConnectionString(btsDbServerName, btsMgntDbName);
                foreach (Application application in root.Applications)
                {
                    if (application.Name == sBtsAppName)
                    {
                        foreach (BtsOrchestration orch in application.Orchestrations)
                        {
                            orch.Host = null;
                            for (int i = 0; i < orch.Ports.Count; i++)
                            {
                                PortType pt = orch.Ports[i].PortType;
                                try
                                {
                                    orch.Ports[i].ReceivePort = null;
                                    orch.Ports[i].SendPort = null;
                                    orch.Ports[i].SendPortGroup = null;
                                }
                                catch (Exception e)
                                {
                                    System.Diagnostics.Debug.WriteLine(e.Message + Environment.NewLine + e.StackTrace);
                                    Logger.doLog(Guid.NewGuid().ToString(), e.Message, Logger.ServerityLevel.ERROR);
                                    Logger.doLog(Guid.NewGuid().ToString(), e.StackTrace, Logger.ServerityLevel.ERROR);
                                }

                            }
                        }
                        break;
                    }
                }
                root.SaveChanges();
                return true;
            }
            catch (Exception exception)
            {
                root.DiscardChanges();
                System.Diagnostics.Debug.WriteLine(exception.Message + Environment.NewLine + exception.StackTrace);
                Logger.doLog(Guid.NewGuid().ToString(), exception.Message, Logger.ServerityLevel.ERROR);
                Logger.doLog(Guid.NewGuid().ToString(), exception.StackTrace, Logger.ServerityLevel.ERROR);
                throw exception;
            }
            finally
            {
                if(root!=null) root.Dispose();
                root = null;
            }
        }
        public static List<GML.BizTalk.OperationManager.MSBTSOperations.Orchestration> GetOrchestrations(List<BtsOrchestration> selectedBtsOrchs, string btsAppName)
        {
            GML.BizTalk.OperationManager.MSBTSOperations.Orchestration GMLOrch = null;
            GML.BizTalk.OperationManager.MSBTSOperations.BtsAssembly GMLAssembly = null;
            List<GML.BizTalk.OperationManager.MSBTSOperations.Orchestration> result = new List<MSBTSOperations.Orchestration>();
            try
            {


                foreach (BtsOrchestration btsOrch in selectedBtsOrchs)
                {
                    GMLAssembly = new GML.BizTalk.OperationManager.MSBTSOperations.BtsAssembly();
                    GMLAssembly.Culture = btsOrch.BtsAssembly.Culture;
                    GMLAssembly.DisplayName = btsOrch.BtsAssembly.DisplayName;
                    GMLAssembly.Name = btsOrch.BtsAssembly.Name;
                    GMLAssembly.PublicKeyToken = btsOrch.BtsAssembly.PublicKeyToken;
                    GMLAssembly.Version = btsOrch.BtsAssembly.Version;

                    GMLOrch = new GML.BizTalk.OperationManager.MSBTSOperations.Orchestration();
                    GMLOrch.BtsAssembly = GMLAssembly;
                    GMLOrch.Fullname = btsOrch.FullName;
                    GMLOrch.Hostname = ((btsOrch.Host == null) ? null : btsOrch.Host.Name);
                    GMLOrch.Status = btsOrch.Status.ToString();
                    GMLOrch.ApplicationName = btsAppName;
                    GMLOrch.BtsDbServerName = string.Empty; // btsDbServerName;
                    GMLOrch.BtsManagmentDbName = string.Empty; // btsMgntDbName;

                    result.Add(GMLOrch);
                }
                return result;
            }
            catch (Exception e)
            {
                Logger.doLog(Guid.NewGuid().ToString(), e.Message, Logger.ServerityLevel.ERROR);
                Logger.doLog(Guid.NewGuid().ToString(), e.StackTrace, Logger.ServerityLevel.ERROR);
                throw;
            }
            finally
            {
                GMLOrch = null;
                GMLAssembly = null;
            }
        }
    }



}
